import PQueue from "../utils/p-queue/index"

const defaultConfig = {
  size: "mini",
  placeholder: "",
}

const options = [
  ["YES", "oem-uat-pdacore"],
  ["NO", "oem-uat-pdacore1"],
]

const columnName = "jm-column"

const isKey = (config, key) => Object.hasOwnProperty.call(config, key)

const JMSelect = {
  componentName: "JMSelect",
  functional: true,
  render(h, context) {
    const optionList = options.map(([label, value]) =>
      h("el-option", { props: { label, value } })
    )
    return h(
      "el-select",
      {
        props: context.props,
        on: {
          input: (value) => {
            context.listeners.input(value)
          },
        },
      },
      optionList
    )
  },
}

const JMInput = {
  componentName: "JMInput",
  functional: true,
  render(h) {
    return h("el-input", { props: context.props })
  },
}

const JMNumber = {
  componentName: "JMNumber",
  functional: true,
  render(h) {
    return h("el-input-number", { props: context.props })
  },
}

const Config = {
  select: JMSelect,
  input: JMInput,
  "input-number": JMNumber,
}

function filterChildren(type, val) {
  if (!type) return val
  const { componentName } = Config[type]
  switch (componentName) {
    case "JMSelect":
      return options.find(([value, label]) => label === val).at(0)
    case "JMInput":
      break
    case "JMNumber":
      break
    default:
      return val
  }
}

export default {
  name: "AsyncTableColumn",
  props: {
    edit: {
      type: Boolean,
      default: false,
    },
    prop: {
      type: String,
      required: true,
    },
    label: {
      type: String,
      required: true,
    },
    type: {
      type: String,
      default: "", // select
    },
    action: {
      type: [Function],
      required: true,
    },
    concurrency: {
      type: Number,
      default: 1,
    },
    autoStart: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      asyncTask: null,
      queue: null,
    }
  },
  inject: ["asyncDialog"],
  watch: {
    'asyncDialog.show': {
      handler(vis) {
        if(vis) {
          this.generateTask()
        }
      },
      immediate: true
    }
  },
  render(h) {
    return h("el-table-column", {
      props: this.$props,
      scopedSlots: {
        default: (props) => {
          props.$cacheValue = props.row[this.prop]
          const children = this.type
            ? [
                h(Config[this.type], {
                  props: Object.assign(
                    { value: props.row[this.prop] },
                    defaultConfig
                  ),
                  on: {
                    input: (val) => {
                      props.row[this.prop] = val
                      if (isKey(props.row, "cellEdit")) {
                        if (props.$cacheValue !== props.row[this.prop]) {
                          props.row.cellEdit = true
                        } else {
                          props.row.cellEdit = false
                        }
                      }
                    },
                  },
                }),
              ]
            : null
          return h(
            "div",
            { style: `white-space: normal;` },
            this.edit
              ? children
              : [h("span", filterChildren(this.type, props.row[this.prop]))]
          )
        },
      },
      ref: columnName,
    })
  },
  computed: {
    columnRef() {
      return this.$refs[columnName]
    }
  },
  methods: {
    generateTask() {
      if (this.queue) {
        this.queue.clear()
      }
      this.queue = new PQueue({
        autoStart: this.autoStart,
        concurrency: this.concurrency,
      })
      this.queue.addAll(
        this.asyncDialog.execList.map(
          (row, index) => () => this.action({ ...row, $index: index })
        )
      )
      this.queue.onIdle().then(() => {
        this.$emit("column-success")
        console.log("All column tasks completed")
      })
    }
  },
}
